package tt.dz.egobus.servicemanager.facade.interator;

import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.convert.converter.Converter;
import tt.dz.egobus.dubbo.scanner.*;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * @author Anson
 * @date 17-3-20
 * @name
 * @since 1.0.1
 */
public class ClassPathScanFacadeContext implements FacadeContext {

    private DefaultPatternResolverProvider patternResolverProvider = new DefaultPatternResolverProvider();
    private String basePackage ="tt.dz.egobus.servicemanager.facade";
    private Map<String, Class<?>> services;

    @Override
    public void doScan() {
        SpringPatternResolverAdapter springPatternResolverAdapter = this.patternResolverProvider.facotry();
        ClassPathResourceFilter filter = new DefaultClassPathResourceFilter();
        this.services = filter.filterClassPath(this.basePackage, springPatternResolverAdapter,
                new FilterScannerClass() {
                    @Override
                    public boolean filter(Class<?> clazz) {
                        return AnnotationUtils.isAnnotationDeclaredLocally(Facade.class, clazz);
                    }
                }, new Converter<Class<?>[], Map<String, Class<?>>>() {
                    @Override
                    public Map<String, Class<?>> convert(Class<?>[] classes) {
                        Map<String, Class<?>> map = new HashMap<String, Class<?>>(0);
                        if (classes == null || classes.length == 0) {
                            return map;
                        }
                        Facade facade = null;
                        for (Class<?> clazz : classes) {
                            facade = AnnotationUtils.findAnnotation(clazz, Facade.class);
                            if (facade == null) {
                                continue;
                            }
                            map.putIfAbsent(facade.facadeName(), clazz);
                        }
                        return map;
                    }
                });
    }

    @Override
    public Class<?> getBean(String facadeName) {
        return (this.services != null ? this.services.get(facadeName) : null);
    }

    @Override
    public Collection<Class<?>> facadeClasses() {
        return this.services == null ? null : this.services.values();
    }


    @Override
    public Iterator<Map.Entry<String, Class<?>>> iterator() {
        return this.services == null ? null : this.services.entrySet().iterator();
    }
}
